<script setup lang="ts">
import { onMounted, ref } from "vue"
import { cloneDeep } from "lodash-es"
import { ElMessage, ElMessageBox, FormInstance, UploadInstance, UploadRequestOptions } from "element-plus"

import { uploadFile } from "@/api/file"
import { advertisingFormRules } from "./rules"
import { addAdvertising, deleteAdvertising, getAdvertisingList, updateAdvertising } from "@/api/admin"
import { AdvertisingFormItem } from "@/api/admin/types"

const DEFAULT_FORM = {
  advertisingTitle: "",
  advertisingContent: "",
  redirectUrl: ""
}

const formRefs = ref<FormInstance[]>([])
const uploadRefs = ref<UploadInstance[]>([])
const forms = ref<AdvertisingFormItem[]>([])

const handleAddForm = () => {
  forms.value.push(cloneDeep(DEFAULT_FORM))
}

const handleUpload = (opts: UploadRequestOptions) => {
  const form = new FormData()
  form.append("file", opts.file)
  form.append("biz", "system_advertising")
  return uploadFile(form)
}

const handleUploadSuccess = ({ data }: ApiResponseData<string>, index: number) => {
  forms.value[index].redirectUrl = data
}

const handleReplaceImage = (index: number) => {
  const input = document.createElement("input")
  input.type = "file"
  input.accept = "image/*"
  input.onchange = (e) => {
    const file = (e.target as HTMLInputElement).files?.[0]
    if (file) {
      const formData = new FormData()
      formData.append("file", file)
      formData.append("biz", "system_advertising")
      uploadFile(formData).then(({ data }) => {
        forms.value[index].redirectUrl = data
      })
    }
  }
  input.click()
}

const handleRemoveImage = (index: number) => {
  uploadRefs.value[index]?.clearFiles()
  forms.value[index].redirectUrl = ""
}

const handleFormSubmit = (index: number) => {
  formRefs.value[index]?.validate((valid) => {
    if (!valid) return void console.error("表单验证失败 => ", formRefs.value[index])
    const form = forms.value[index]
    const api = form.id ? updateAdvertising : addAdvertising
    // @ts-expect-error
    api(form).then(() => {
      ElMessage.success("提交成功")
      getAdvertisingList().then(({ data }) => {
        forms.value = data.records
      })
    })
  })
}

const handleFormDelete = (val: string | number) => {
  if (typeof val === "number") return void forms.value.splice(val, 1)
  ElMessageBox.confirm("确定删除这条广告吗？").then(() => {
    deleteAdvertising({ id: val }).then(() => {
      ElMessage.success("删除成功")
      getAdvertisingList().then(({ data }) => {
        forms.value = data.records
      })
    })
  })
}

onMounted(() => {
  getAdvertisingList().then(({ data }) => {
    forms.value = data.records
  })
})
</script>

<template>
  <div class="app-container">
    <el-card shadow="never" class="mb-5">
      <el-button type="primary" @click="handleAddForm">新增表单</el-button>
    </el-card>
    <div class="forms-wrapper">
      <el-card v-for="(form, index) in forms" :key="index" shadow="hover">
        <el-form
          :ref="(el) => (formRefs[index] = el as FormInstance)"
          :model="form"
          :rules="advertisingFormRules"
          label-width="80px"
        >
          <el-form-item label="广告名称" prop="advertisingTitle">
            <el-input v-model="form.advertisingTitle" maxlength="80" show-word-limit clearable />
          </el-form-item>
          <el-form-item label="广告描述" prop="advertisingContent">
            <el-input v-model="form.advertisingContent" type="textarea" maxlength="300" show-word-limit clearable />
          </el-form-item>
          <el-form-item label="广告图片" prop="redirectUrl">
            <el-upload
              :ref="(el) => (uploadRefs[index] = el as UploadInstance)"
              class="upload-advertising-image"
              action="#"
              :auto-upload="true"
              accept="image/*"
              :show-file-list="false"
              :limit="1"
              :http-request="handleUpload"
              :on-success="(response) => handleUploadSuccess(response, index)"
            >
              <span class="upload-content">
                <template v-if="!form.redirectUrl">
                  <span class="upload-icon">
                    <el-icon :size="24"><Upload /></el-icon>
                  </span>
                </template>
                <template v-else>
                  <div @click.stop class="upload-preview">
                    <img :src="form.redirectUrl" width="120" height="90" style="object-fit: cover" alt="上传图片" />
                    <div class="upload-actions">
                      <span class="upload-actions__replace mr-8px" @click="handleReplaceImage(index)">
                        <el-icon :size="24" color="#eae5e3"><Upload /></el-icon>
                      </span>
                      <span class="upload-actions__delete" @click.stop="handleRemoveImage(index)">
                        <el-icon :size="24" color="#eae5e3"><Delete /></el-icon>
                      </span>
                    </div>
                  </div>
                </template>
              </span>
            </el-upload>
          </el-form-item>
        </el-form>
        <el-form-item>
          <el-button type="primary" class="ml-80px" @click="handleFormSubmit(index)">提交</el-button>
          <el-button type="danger" @click="handleFormDelete(form?.id ?? index)">删除</el-button>
        </el-form-item>
      </el-card>
    </div>
  </div>
</template>

<style scoped lang="scss" src="./style.scss"></style>
